from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection
import json

import logging,random
logger = logging.getLogger('django')

from focus_on_rent.libs.captcha.captcha import captcha
from celery_tasks.sms.tasks import send_sms_verify_code


class ImageCodeView(View):
    '''返回图形验证码类视图'''

    def get(self, request):

        cur = request.GET.get('cur')
        # pre = request.GET.get('pre')
        # 1.调用工具类 captcha 生成图形验证码
        text, image = captcha.generate_captcha()

        # 2.链接 redis, 获取链接对象
        redis_conn = get_redis_connection('verify_code')

        # 3.利用链接对象, 保存数据到 redis, 使用 setex 函数
        # redis_conn.setex('<key>', '<expire>', '<value>')
        redis_conn.setex('img_%s' % cur, 300, text)
        # redis_conn.setex('pre_%s' % pre, 300, text)

        # 4.返回(图片)
        return HttpResponse(image,
                            content_type='image/jpg')


class SMSCodeView(View):

    def post(self, request):
        '''接收参数，检验，发送短信验证码'''

        # 1.接收post传参
        json_dict = json.loads(request.body.decode())
        mobile = json_dict.get('mobile')
        id = json_dict.get('id')
        text_client = json_dict.get('text')

        # 2.优化1：避免频繁发送短信，将这句话提到前面最开始的地方
        redis_conn = get_redis_connection('verify_code')
        # 进入函数后，现货区存储在redis中的数据
        send_flag = redis_conn.get('send_flag_%s' % mobile)

        # 3.查看数据是否存在，如果存在，说明60s没过，返回
        if send_flag:
            return JsonResponse({'errno': 4201,
                                 'errmsg': '非法请求或请求次数受限'})

        # 4.如果过了，再执行下面代码：总体验证(查看参数是否为空)
        if not all([mobile, id, text_client]):
            return JsonResponse({'errno': 4002,
                                 'errmsg': '无数据'})

        # 5.从redis中取出图形验证码
        text_server = redis_conn.get('img_%s' % id)

        # 6.判断服务端的图形验证码是否过期，如果过期，return
        if text_server is None:
            return JsonResponse({'errno': 4002,
                                 'errmsg': '无数据'})

        # 7.删除redis中的图形验证码
        try:
            redis_conn.delete('img_%s' % id)
        except Exception as e:
            logger.error(e)

        # 8.对比前后端的图形验证码，bytes 转字符串
        text_server = text_server.decode()
        # 转小写后比较
        if text_client.lower() != text_server.lower():
            return JsonResponse({'errno': 4103,
                                 'errmsg': '参数错误'})

        # ,9.随机生成6位短信验证码
        sms_code = '%06d' % random.randint(0, 999999)
        logger.info(sms_code)

        # 10.优化2：用pipeline创建redis管道操作数据库
        # 创建 redis 管道
        p1 = redis_conn.pipeline()
        # 将 redis 请求添加到列队
        p1.setex('sms_%s' % mobile, 300, sms_code)
        p1.setex('send_flag_%s' % mobile, 60, 1)
        # 执行请求，这步不能少
        p1.execute()

        # 11.优化3：通过Celery异步操作实现主线跟短信平台分离,注意: 这里的函数,调用的时候需要加: .delay()
        send_sms_verify_code.delay(mobile, sms_code)

        # 12.返回json
        return JsonResponse({'errno': 0,
                             'errmsg': '发送成功'})
